package com.sl.ms.sms.service.impl;

import cn.hutool.core.stream.StreamUtil;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sl.ms.sms.dto.SendResultDTO;
import com.sl.ms.sms.dto.SmsInfoDTO;
import com.sl.ms.sms.entity.SmsRecordEntity;
import com.sl.ms.sms.entity.SmsThirdChannelEntity;
import com.sl.ms.sms.enums.SendStatusEnum;
import com.sl.ms.sms.enums.SmsExceptionEnum;
import com.sl.ms.sms.handler.HandlerFactory;
import com.sl.ms.sms.handler.SmsSendHandler;
import com.sl.ms.sms.mapper.SmsRecordMapper;
import com.sl.ms.sms.service.RouteService;
import com.sl.ms.sms.service.SmsService;
import com.sl.transport.common.exception.SLException;
import com.sl.transport.common.util.BeanUtil;
import com.sl.transport.common.util.ObjectUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
public class SmsServiceImpl extends ServiceImpl<SmsRecordMapper, SmsRecordEntity> implements SmsService  {
    @Resource
    private RouteService routeService;

    @Override
    public List<SendResultDTO> sendSms(SmsInfoDTO smsInfoDTO) {
        //路由短信发送通道
        SmsThirdChannelEntity smsThirdChannelEntity = routeService.route(smsInfoDTO.getSmsType(),
                smsInfoDTO.getContentType(), smsInfoDTO.getSmsCode());

        if (ObjectUtil.isEmpty(smsThirdChannelEntity)) {
            throw new SLException(SmsExceptionEnum.SMS_CHANNEL_DOES_NOT_EXIST);
        }

        //获取service
        SmsSendHandler smsSendHandler = HandlerFactory.get(smsThirdChannelEntity.getSendChannel(), SmsSendHandler.class);
        if (ObjectUtil.isEmpty(smsSendHandler)) {
            throw new SLException(SmsExceptionEnum.SMS_CHANNEL_DOES_NOT_EXIST);
        }

        //生成批次id
        long batchId = IdWorker.getId();

        //封装数据
        List<SmsRecordEntity> smsRecordEntities = StreamUtil.of(smsInfoDTO.getMobiles())
                .map(mobile -> SmsRecordEntity.builder()
                        .batchId(batchId) //批次id
                        .appName(smsInfoDTO.getAppName()) //微服务名称
                        .smsContent(smsInfoDTO.getSmsContent()) //短信内容
                        .sendChannelId(smsThirdChannelEntity.getId()) //发送渠道id
                        .mobile(mobile) //手机号
                        .status(SendStatusEnum.FAIL) //默认失败状态
                        .build())
                .collect(Collectors.toList());

        //发送短信
        smsSendHandler.send(smsThirdChannelEntity, smsRecordEntities);

        //入库
        super.saveBatch(smsRecordEntities);

        return BeanUtil.copyToList(smsRecordEntities, SendResultDTO.class);
    }


    /*@Resource
    private ALiyunSmsConfigur aliyunSmsConfigur;
    @Resource
    private SlSmsThirdChannelService slSmsThirdChannelService;
    @Resource
    private SlSmsRecordService slSmsRecordService;
    //验证码的模板code
    private static final String TEMPLATE_Code = "SMS_472775041";
    //短信的模板-注册新用户code
    private static final String TEMPLATE_Phone = "SMS_472645069";
    //短信的模板-更换手机号code
    private static final String TEMPLATE_UpdatePhone = "SMS_472830062";

    //注册新用户
    @Override
    public String sendPhone(String phoneNum) {
        Map<String, Object> map = new HashMap<>();
        map.put("phone", phoneNum);
        String message = sendSms(phoneNum, TEMPLATE_Phone, map);
        if(StrUtil.equals("OK",message)){
            this.saveRecordAndChannel(phoneNum,TEMPLATE_Phone);
        }
        return message;
    }

    //发送验证码
    @Override
    public String sendCode(String phoneNum,String code) {
        Map<String, Object> map = new HashMap<>();
        map.put("code", code);
        String message = sendSms(phoneNum, TEMPLATE_Code, map);
        if(StrUtil.equals("OK",message)){
            this.saveRecordAndChannel(phoneNum,TEMPLATE_Code);
        }
        return message;
    }

    //更换手机号
    @Override
    public String sendUpdatePhone(String phoneNum) {
        Map<String, Object> map = new HashMap<>();
        map.put("phone", phoneNum);
        String message = sendSms(phoneNum, TEMPLATE_UpdatePhone, map);
        if(StrUtil.equals("OK",message)){
            this.saveRecordAndChannel(phoneNum,TEMPLATE_UpdatePhone);
        }
        return message;
    }

    private String sendSms(String phoneNum, String templateCode, Map<String, Object> map) {
        // 初始化请求客户端
        Client client = null;
        try {
            client = this.createClient();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        // 构造请求对象，请填入请求参数值
        SendSmsRequest sendSmsRequest = new SendSmsRequest()
                .setPhoneNumbers(phoneNum)
                .setSignName(aliyunSmsConfigur.getSignName())
                .setTemplateCode(templateCode);
        sendSmsRequest.setTemplateParam(JSONUtil.toJsonStr(map));
        // 获取响应对象
        SendSmsResponse sendSmsResponse = null;
        try {
            sendSmsResponse = client.sendSms(sendSmsRequest);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        SendSmsResponseBody body = sendSmsResponse.getBody();
        // 解析整个JSON字符串
        JSONObject jsonObject = JSONUtil.parseObj(body);
        String message = jsonObject.getStr("message");
        return message;
    }

    private Client createClient() throws Exception {
        Config config = new Config()
                // 配置 AccessKey ID
                .setAccessKeyId(aliyunSmsConfigur.getAccessKeyId())
                // 配置 AccessKey Secret
                .setAccessKeySecret(aliyunSmsConfigur.getAccessKeySecret())
                .setRegionId(aliyunSmsConfigur.getRegionId());
        // 配置 Endpoint
        config.endpoint = "dysmsapi.aliyuncs.com";
        return new Client(config);
    }


    private void saveRecordAndChannel(String phoneNum,String templateCode){
        SlSmsThirdChannel slSmsThirdChannelServiceOne = slSmsThirdChannelService.getOne(Wrappers.<SlSmsThirdChannel>lambdaQuery()
                .eq(SlSmsThirdChannel::getSignName, aliyunSmsConfigur.getSignName())
                .eq(SlSmsThirdChannel::getTemplateCode, templateCode));
        if(ObjectUtil.isEmpty(slSmsThirdChannelServiceOne)) {
            SlSmsThirdChannel build = SlSmsThirdChannel.builder()
                    .smsType(SmsTypeEnum.NOTICE.getCode())
                    .contentType(SmsContentTypeEnum.WORD_MESSAGE.getCode())
                    .smsCode(1001)
                    .templateCode(templateCode)
                    .sendChannel(1)
                    .signName(aliyunSmsConfigur.getSignName())
                    .smsPriority(1)
                    .account("{\n" +
                            "    \"accessKeyId\": \"xxxxxxx\",\n" +
                            "    \"accessKeySecret\": \"xxxxxxx\",\n" +
                            "    \"endpoint\": \"dysmsapi.aliyuncs.com\"\n" +
                            "}")
                    .status(SendStatusEnum.SUCCESS.getCode())
                    .created(LocalDateTime.now())
                    .updated(LocalDateTime.now())
                    .isDelete(false)
                    .build();
            slSmsThirdChannelService.save(build);
            SlSmsRecord build1 = SlSmsRecord.builder()
                    .sendChannelId(build.getId())
                    .batchId(12L)
                    .appName("sl-express-ms-web-customer")
                    .mobile(phoneNum)
                    .smsContent("123")
                    .status(SendStatusEnum.SUCCESS.getCode())
                    .created(LocalDateTime.now())
                    .updated(LocalDateTime.now())
                    .build();
            slSmsRecordService.save(build1);
        }else{
            SlSmsRecord build1 = SlSmsRecord.builder()
                    .sendChannelId(slSmsThirdChannelServiceOne.getId())
                    .batchId(12L)
                    .appName("sl-express-ms-web-customer")
                    .mobile(phoneNum)
                    .smsContent("123")
                    .status(SendStatusEnum.SUCCESS.getCode())
                    .created(LocalDateTime.now())
                    .updated(LocalDateTime.now())
                    .build();
            slSmsRecordService.save(build1);
        }
    }

*/
}
